/*************************************************************************
                           MenuTache  -  description
                             -------------------
    début                : MenuTache
    copyright            : (C) MenuTache par XXX
    e-mail               : MenuTache
*************************************************************************/

//---------- Réalisation de la tâche <MenuTache> (fichier MenuTache.cpp) ---

/////////////////////////////////////////////////////////////////  INCLUDE
//-------------------------------------------------------- Include système

//------------------------------------------------------ Include personnel
#include "MenuTache.h"
#include "/public/tp/tp-multitache/Outils.h"
#include "/public/tp/tp-multitache/Voiture.h"
#include "/public/tp/tp-multitache/Menu.h"
#include <signal.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <iostream>

using namespace std;
///////////////////////////////////////////////////////////////////  PRIVE
//------------------------------------------------------------- Constantes

//------------------------------------------------------------------ Types

//---------------------------------------------------- Variables statiques
//Sémaphore pour la memoire partagée tempoFeu:
static int semTempoFeu;
//Structures d'opérations sur le sémaphores :
static struct sembuf reserverTempoFeu = {0, -1, 0};
static struct sembuf libererTempoFeu = {0, 1, 0};
//Mémoire partagée tempoFeu:
static unsigned int *shmTempoFeu;
//File de message BALvoiture : 
static int BALvoiture;
//Numero des voitures créés manuellement :
static unsigned int numVoiture = 1;
//Etat du générateur :
static bool etatGen = true;
//PID du générateur :
static pid_t genPID;
//------------------------------------------------------ Fonctions privées
//static type nom ( liste de paramètres )
// Mode d'emploi :
//
// Contrat :
//
// Algorithme :
//
//{
//} //----- fin de nom

//////////////////////////////////////////////////////////////////  PUBLIC
//---------------------------------------------------- Fonctions publiques
// Algorithme :
//

void Commande (char code)
{
	if ( code=='f' || code=='F' )
	{
		cerr << "demande de quiter l'appli, fin de la tache menu" <<endl;
		semctl ( semTempoFeu,0,SETVAL,1 );
		exit ( 0 );
	}
	else if ( code=='g' || code=='G')
	{
		if ( etatGen )
		{
			cerr << "arret du générateur" << endl;
			if(!kill (genPID, SIGSTOP))
			{
				etatGen = false;
				Effacer (ETAT_GENERATEUR);
				Afficher (ETAT_GENERATEUR, "Off", GRAS);
			}else{
			cerr << "echec" << endl;
			}
		}
		else
		{
			cerr << "demarage du générateur" <<endl;
			if(!kill (genPID, SIGCONT))
			{
				etatGen = true;
				Effacer (ETAT_GENERATEUR);
				Afficher (ETAT_GENERATEUR, "On", GRAS, INVERSE);
			}else{
			cerr << "echec" << endl;
			}
		}
	}
	else
	{
		cerr << "appui sur "<< code <<" illicite" << endl;
	}
}

void Commande (TypeVoie entree, TypeVoie sortie)
{
	cerr << "création d'une voiture" << endl;
	if ( numVoiture<200 )
	{
		struct Voiture nouvelleVoiture = { entree, sortie, numVoiture};
		struct MsgVoiture nouvMsgVoiture = { entree, nouvelleVoiture };
		if ( msgsnd (BALvoiture, &nouvMsgVoiture, TAILLE_MSG_VOITURE, IPC_NOWAIT))
		{
			Afficher (MESSAGE, "TROP DE VOITURES EN ATTENTE", STANDARD, INVERSE); 
		}
		else
		{
			OperationVoie (PLUS,entree);
			Effacer(NUMERO);
			Effacer(ENTREE);
			Effacer(SORTIE);
			Afficher(NUMERO,numVoiture);
			Afficher(ENTREE,entree);
			Afficher(SORTIE,sortie);
			numVoiture++;
		}

		
	}
}

void Commande (TypeVoie voie, unsigned int duree)
{
	if ( voie==EST || voie==OUEST )
	{
		semop(semTempoFeu, &reserverTempoFeu, 1);
		*shmTempoFeu &= 0xFFFF0000;
		*shmTempoFeu |= duree;
		semop(semTempoFeu, &libererTempoFeu, 1);
		cerr << " changement de la tempo du feu sur la voie E-O avec la valeur " << duree << endl;
	}
	else
	{
		semop(semTempoFeu, &reserverTempoFeu, 1);
		*shmTempoFeu &= 0xFFFF;
		*shmTempoFeu |= (duree << 16); 
		semop(semTempoFeu, &libererTempoFeu, 1);
		cerr << " changement de la tempo du feu sur la voie N-S avec la valeur "<< duree << endl;
	}
}
void IniMenu ( void* ATempoFeu, int SFeu, pid_t GenerateurPid, int BALVoiture )
{
	shmTempoFeu = (unsigned int*)ATempoFeu;
	semTempoFeu = SFeu;

	genPID = GenerateurPid;
	if(!kill (genPID, SIGCONT))
	{
		etatGen = true;
		Effacer (ETAT_GENERATEUR);
		Afficher (ETAT_GENERATEUR, "On", GRAS, INVERSE);
	}else{
		cerr << "echec" << endl;
	}

	BALvoiture = BALVoiture;
	*shmTempoFeu = 0x0017000C;//Initialise la tempo a 12s pour E-O, 23 pour N-S
	Menu();
}
